package com.mbg.plus.plugins;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import static org.mybatis.generator.internal.util.StringUtility.isTrue;

/**
 * Generator Lombok 插件
 * Data注解默认引入
 *
 * @author ZhuYinglong
 * @date 2020/3/17
 */
public class LombokPlugin extends PluginAdapter {

    private Set<LombokAnnotation> lombokAnnotations;

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        lombokAnnotations = new HashSet<>();
        lombokAnnotations.add(LombokAnnotation.DATA);
        for (String propertyName : properties.stringPropertyNames()) {
            if (!isTrue(properties.getProperty(propertyName))) {
                if(LombokAnnotation.DATA.propertyName.toUpperCase().equals(propertyName.toUpperCase())) {
                    lombokAnnotations.remove(LombokAnnotation.DATA);
                }
                continue;
            }
            LombokAnnotation lombokAnnotation = LombokAnnotation.getByPropertyName(propertyName);
            if (lombokAnnotation != null) {
                lombokAnnotations.add(lombokAnnotation);
            }
        }
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }

    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addAnnotations(topLevelClass);
        return true;
    }

    private void addAnnotations(TopLevelClass topLevelClass) {
        for (LombokAnnotation annotations : lombokAnnotations) {
            topLevelClass.addAnnotation(annotations.annotationName);
            topLevelClass.addImportedType(annotations.javaType);
        }
    }

    private enum LombokAnnotation {

        DATA("data", "@Data", "lombok.Data"),
        NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
        ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
        BUILDER("builder", "@Builder", "lombok.Builder");

        private String propertyName;
        private String annotationName;
        private String javaType;

        LombokAnnotation(String propertyName, String annotationName, String javaType) {
            this.propertyName = propertyName;
            this.annotationName = annotationName;
            this.javaType = javaType;
        }

        static LombokAnnotation getByPropertyName(String propertyName) {
            for (LombokAnnotation value : LombokAnnotation.values()) {
                if (value.propertyName.toUpperCase().equals(propertyName.toUpperCase())) {
                    return value;
                }
            }
            return null;
        }

    }


}
